
package com.smartfit;

import java.util.ArrayList;

import com.charts.view.LineChart;
import com.smartfit.AccelSensorData;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;

public class CompareActivity extends AccelerometerSensorActivity implements OnClickListener
{
	private enum CompareState
	{
		DEFAULT ,
		PRESS_START_BUTTON ,
		PRESS_STOP_BUTTON ,
	};

	// 데이터 ID
	private int m_iExamplarID = 0;
	// 현재 작업 중인 데이터
	private AccelValueFileData m_AccelValueFileData = new AccelValueFileData();
	
	// 스타트 검증
	
	boolean m_bIsStarted;
	boolean m_bIsNeedCheckFirstFrame;
	
	Axis3f m_PrevAccelValue;
	Axis3f m_CurrAccelValue;

	//
	
	ChartLine m_AccelChartLine;
	ChartLine m_AngleChartLine;
	
	TextView m_AccelValue;
	TextView m_Result;
	
	private ListView m_ListView = null;
	
	// pattern
	final int PATTERN_SIZE = 20;
	int [] m_piCurrentPatterns;
	int [] m_piPatternQueueIndexs;
	int [][] m_ppiPatterns;
	
	TextView m_InfectionPoint;
	TextView m_InfectionPoint2;
	
	int m_iNumPatterns;
	int m_iPatternQueueIndex;

	// 패턴변화
	Axis3f m_UpPattern;
	Axis3f m_LowPattern;
	int [][] m_ppiPatternsFinally;
	
	//
	Axis3f [][] m_ppTangentValues;
	// 최종 패턴
	int [] m_piPatternsFinally;
	// X
	public ArrayList<Double> [] m_pTangentXs;
	
	//
	PatternFinder [] m_pPatternFinder;
	
	@Override
	protected void onCreate( Bundle savedInstanceState )
	{
		// TODO Auto-generated method stub
		super.onCreate( savedInstanceState );
		setContentView( R.layout.compare_activity );

		// 센서 초기화
		InitializeSensor();

		// 센서 정보 저장 시작
		Button btnCmpStart = ( Button )findViewById( R.id.CmpStartButton );
		btnCmpStart.setOnClickListener( this );
		// 센서 정보 저장 종료
		Button btnCmpStop = ( Button )findViewById( R.id.CmpStopButton );
		btnCmpStop.setOnClickListener( this );

		// 비교화면에서 메인화면으로 전환
		Button btnMain = ( Button )findViewById( R.id.CmpMainButton );
		btnMain.setOnClickListener( this );

		// 버튼 활성화 처리
		ControlButton( CompareState.DEFAULT );

		// 스타트 검증
		
		m_bIsStarted = false;
		m_bIsNeedCheckFirstFrame = true;
		
		m_PrevAccelValue = new Axis3f();
		m_CurrAccelValue = new Axis3f();

		// 라인차트
		m_AccelChartLine = new ChartLine( (LineChart)findViewById( R.id.compare_accel_line_chart ) );
		m_AngleChartLine = new ChartLine( (LineChart)findViewById( R.id.compare_angle_line_chart ) );
		
		// text view
		m_AccelValue = ( TextView )findViewById( R.id.cmp_acc_value );
		m_Result = ( TextView )findViewById( R.id.cmp_result );

		m_ListView = ( ListView )findViewById( R.id.compare_history_list );
		SetListViewHeightBasedOnChildren( m_ListView );
		
		// pattern
		m_piCurrentPatterns = new int[3];
		m_piPatternQueueIndexs = new int[3];
		m_ppiPatterns = new int[3][PATTERN_SIZE];
		m_ppiPatternsFinally = new int[3][PATTERN_SIZE];
		
		/*
		for ( int i = 0 ; i < 3 ; i++ )
		{
			m_piCurrentPatterns[i] = 0;
			m_piPatternQueueIndexs[i] = 0;
			
			m_ppiPatterns[i] = new int[PATTERN_SIZE];
		}
		*/
		
		m_iNumPatterns = 0;

		// 패턴변화
		// up/down , stable/flexible
		m_ppTangentValues = new Axis3f[2][2];
		
		for ( int i = 0 ; i < 2 ; i++ )
		{
			m_ppTangentValues[i] = new Axis3f[2];
			
			for ( int j = 0 ; j < 2 ; j++ )
			{
				m_ppTangentValues[i][j] = new Axis3f();
			}
		}
		
		m_pTangentXs = new ArrayList[2];
		
		for ( int i = 0 ; i < 2 ; i++ )
		{
			m_pTangentXs[i] = new ArrayList<Double>();
		}
		
		m_piPatternsFinally = new int[3];
		
		//
		m_pPatternFinder = new PatternFinder[3];
		
		for ( int i = 0 ; i < 3 ; i++ )
		{
			m_pPatternFinder[i] = new PatternFinder();
		}
	}

	private void ClickStartButton()
	{
		SmartFitApp app = ( ( SmartFitApp )getApplicationContext() );
		
		if ( app.m_ExamplarDB.IsExistExamplar( m_iExamplarID ) == false )
		{
			if ( app.m_ExamplarDB.LoadExamplar( m_iExamplarID ) == false )
			{
				// 비교할 데이터 없음
				ShowNotFoundExamplar();
				
				return;
			}
		}
		
		//  새로 데이터 저장 시작
		m_AccelValueFileData.Clear();

		//
		if ( app.m_ExamplarDB.IsEnabledCheckStart() )
		{
			m_bIsStarted = false;
			m_bIsNeedCheckFirstFrame = true;
		}
		else
		{
			m_bIsStarted = true;
			m_bIsNeedCheckFirstFrame = false;
		}
		
		m_PrevAccelValue.Clear();
		m_CurrAccelValue.Clear();
		
		// pattern
		
		for ( int i = 0 ; i < 3 ; i++ )
		{
			m_piCurrentPatterns[i] = AccelValueFileData.PATTERN_SAME;
			m_piPatternQueueIndexs[i] = 0;
			
			for ( int j = 0 ; j < PATTERN_SIZE ; j++ )
			{
				m_ppiPatterns[i][j] = AccelValueFileData.PATTERN_SAME;
				m_ppiPatternsFinally[i][j] = AccelValueFileData.PATTERN_SAME;
			}
			
			m_piPatternsFinally[i] = AccelValueFileData.PATTERN_SAME;
		}
		
		m_iPatternQueueIndex = 0;

		for ( int i = 0 ; i < 2 ; i++ )
		{
			for ( int j = 0 ; j < 2 ; j++ )
			{
				m_ppTangentValues[i][j].Clear();
			}
		}
		
		for ( int i = 0 ; i < 2 ; i++ )
		{
			m_pTangentXs[i].clear();
		}
		
		//
		for ( int i = 0 ; i < 3 ; i++ )
		{
			m_pPatternFinder[i].Clear();
			m_pPatternFinder[i].SetDiffThreshold( app.m_ExamplarDB.GetCompareThresholdForPattern() );
		}
		
		ConnectSensor();
		
		//
		
		
		//
		DrawPattern( AccelValueFileData.DATA_X );
		DrawPattern( AccelValueFileData.DATA_Y );
		DrawPattern( AccelValueFileData.DATA_Z );
		// 라인 차트
		m_AccelChartLine.Initialize();
		m_AngleChartLine.Initialize();

		// 버튼 활성화 처리
		ControlButton( CompareState.PRESS_START_BUTTON );

		/*/
		// 테스트
		for ( int i = 1 ; i < 101 ; i++ )
		{
			m_AccelValueFileData.m_iTimeInterval = 100;
			m_AccelValueFileData.Set( 1.2 * i , 1.3 * i , 1.4 * i );
		}
		/**/
	}
	
	private void ClickStopButton()
	{
		DisconnectSensor();
		
		Compare();

		// 버튼 활성화 처리
		ControlButton( CompareState.PRESS_STOP_BUTTON );
	}
	
	private void ControlButton( CompareState eState )
	{
		Button btnCmpStart = ( Button )findViewById( R.id.CmpStartButton );
		Button btnCmpStop = ( Button )findViewById( R.id.CmpStopButton );
		
		
		switch ( eState )
		{
			case PRESS_START_BUTTON:
				
				btnCmpStart.setEnabled( false );
				btnCmpStop.setEnabled( true );

				break;
				
			case PRESS_STOP_BUTTON:

				btnCmpStart.setEnabled( true );
				btnCmpStop.setEnabled( false );
				
				break;
				
			default:
				
				btnCmpStart.setEnabled( true );
				btnCmpStop.setEnabled( false );

				break;
		}
	}
	
	@Override
	public void onClick( View v )
	{
		// TODO Auto-generated method stub
		switch ( v.getId() )
		{
			case R.id.CmpStartButton:
				
				ClickStartButton();
				
				break;

			case R.id.CmpStopButton:
				
				ClickStopButton();
				
				break;

			case R.id.CmpMainButton:
				
				finish();
				
				break;
		}		
	}

	@Override
	public boolean onKeyDown( int keyCode , KeyEvent event )
	{
		switch ( keyCode )
		{
			case KeyEvent.KEYCODE_VOLUME_UP:
				
				ClickStartButton();
				
				return true;
				
			case KeyEvent.KEYCODE_VOLUME_DOWN:
				
				ClickStopButton();
				
				return true;
				
			case KeyEvent.KEYCODE_BACK:
				
				break;
		}

		// TODO Auto-generated method stub
		return super.onKeyDown(keyCode, event);
	}
	
	@Override
	public void NotifySensorEvent( AccelSensorData sensorData )
	{
		m_PrevAccelValue.x = m_CurrAccelValue.x;
		m_PrevAccelValue.y = m_CurrAccelValue.y;
		m_PrevAccelValue.z = m_CurrAccelValue.z;
		
		m_CurrAccelValue.x = sensorData.acceleration[AccelSensorData.SENSOR_CURR_DATA].x;
		m_CurrAccelValue.y = sensorData.acceleration[AccelSensorData.SENSOR_CURR_DATA].y;
		m_CurrAccelValue.z = sensorData.acceleration[AccelSensorData.SENSOR_CURR_DATA].z;
		
		if ( m_bIsStarted )
		{
			
			// 라인 차트
			m_AccelChartLine.Add( m_AccelValueFileData.m_Angle.accelValueXs.size() , 
					m_CurrAccelValue.x * 1000 , 
					m_CurrAccelValue.y * 1000 , 
					m_CurrAccelValue.z * 1000 );
			m_AccelChartLine.ReDrawChart();

			/*
			m_AngleChartLine.Add( m_AccelValueFileData.m_Angle.accelValueXs.size() , 
					sensorData.fPitch * 1000 , 
					sensorData.fRoll * 1000 , 
					sensorData.fTheta * 1000 );
			m_AngleChartLine.ReDrawChart();
			*/

			m_AccelValueFileData.Set( AccelValueFileData.DATA_TYPE_ANGLE , m_CurrAccelValue.x , m_CurrAccelValue.y , m_CurrAccelValue.z );
			
			SmartFitApp app = ( ( SmartFitApp )getApplicationContext() );
			
			AnalyzeInflectionPoint_1( AccelValueFileData.DATA_X , app.m_ExamplarDB.GetCompareFrameForPattern() );
			AnalyzeInflectionPoint_1( AccelValueFileData.DATA_Y , app.m_ExamplarDB.GetCompareFrameForPattern() );
			AnalyzeInflectionPoint_1( AccelValueFileData.DATA_Z , app.m_ExamplarDB.GetCompareFrameForPattern() );
		}
		else
		{
			if ( m_bIsNeedCheckFirstFrame )
			{
				m_bIsNeedCheckFirstFrame = false;
			}
			else
			{
				if ( VerifyStartedActivity( m_PrevAccelValue , m_CurrAccelValue ) == true )
				{
					m_AccelValue.setText( "Start" );
					m_bIsStarted = true;
				}
			}
		}	
	}
	
	@Override
	public void NotifySensorOrientationEvent( double x , double y , double z )
	{
		// TODO Auto-generated method stub

//		String s = "x = " + m_DecimalFormat.format( x ) + " , y = " + m_DecimalFormat.format( y ) + " , z = " + m_DecimalFormat.format( z );
//		m_AccelValue.setText( s );

		m_PrevAccelValue.x = m_CurrAccelValue.x;
		m_PrevAccelValue.y = m_CurrAccelValue.y;
		m_PrevAccelValue.z = m_CurrAccelValue.z;
		
		m_CurrAccelValue.x = x;
		m_CurrAccelValue.y = y;
		m_CurrAccelValue.z = z;

		if ( m_bIsStarted )
		{
			// 라인 차트
			m_AccelChartLine.Add( m_AccelValueFileData.m_Angle.accelValueXs.size() , x * 1000 , y * 1000 , z * 1000 );
			//m_ChartLine.Add( x , y , z );
			m_AccelChartLine.ReDrawChart();
			
			m_AccelValueFileData.Set( AccelValueFileData.DATA_TYPE_ANGLE , m_CurrAccelValue.x , m_CurrAccelValue.y , m_CurrAccelValue.z );
		}
		else
		{
			if ( m_bIsNeedCheckFirstFrame )
			{
				m_bIsNeedCheckFirstFrame = false;
			}
			else
			{
				if ( VerifyStartedActivity( m_PrevAccelValue , m_CurrAccelValue ) == true )
				{
					m_Result.setText( "Start" );
					m_bIsStarted = true;
				}
			}
		}	
	}
	
	public void AnalyzeInflectionPoint_1( int iAxis , int iNumCompareFrameForPattern )
	{
		int iCurrentPattern = m_AccelValueFileData.Analyze_1( iAxis );

		if ( iCurrentPattern == AccelValueFileData.PATTERN_SAME )
		{
			// 현재 가속도센서 값과 이전 가속도 센서값의 패턴변화 없음
			return;
		}
		
		switch ( iAxis )
		{
			case AccelValueFileData.DATA_X:
	
				m_pPatternFinder[iAxis].Analyze( iCurrentPattern , m_CurrAccelValue.x );

				break;

			case AccelValueFileData.DATA_Y:
				
				m_pPatternFinder[iAxis].Analyze( iCurrentPattern , m_CurrAccelValue.y );
				
				break;
			
			case AccelValueFileData.DATA_Z:
				
				m_pPatternFinder[iAxis].Analyze( iCurrentPattern , m_CurrAccelValue.z );
				
				break;
		}

		DrawPattern( iAxis );
	}

	public void DrawPattern( int iAxis )
	{
		String strPattern1 = "";
		String strPattern2 = "";
		
		switch ( iAxis )
		{
			case AccelValueFileData.DATA_X:
				
				strPattern1 += "X(R) : ";
				
				break;

			case AccelValueFileData.DATA_Y:
				
				strPattern1 += "Y(G) : ";
				
				break;
			
			case AccelValueFileData.DATA_Z:
				
				strPattern1 += "Z(B) : ";
				
				break;
		}
		
		int iStart = m_pPatternFinder[iAxis].GetStartIndex();
		int iEnd = m_pPatternFinder[iAxis].GetEndIndex();
		int iMiddle = 0;
		int [] piQueue = m_pPatternFinder[iAxis].GetQueue();
		
		if ( iStart > iEnd )
		{
			iMiddle = PatternFinder.QUEUE_SIZE - 1;
		}
		else
		{
			iMiddle = iEnd;
		}			

		for ( int i = iStart ; i <= iMiddle ; i++ )
		{
			if ( piQueue[i] != AccelValueFileData.PATTERN_SAME )
			{
				if ( piQueue[i] == AccelValueFileData.PATTERN_UP )
				{
					strPattern1 += "↑ "; 
				}
				else if ( piQueue[i] == AccelValueFileData.PATTERN_DOWN )
				{
					strPattern1 += "↓ ";
				}
				else
				{
					strPattern1 += "- ";
				}
			}
		}
		
		if ( iStart > iEnd )
		{
			for ( int i = 0 ; i < iStart ; i++ )
			{
				if ( piQueue[i] != AccelValueFileData.PATTERN_SAME )
				{
					if ( piQueue[i] == AccelValueFileData.PATTERN_UP )
					{
						strPattern1 += "↑ "; 
					}
					else if ( piQueue[i] == AccelValueFileData.PATTERN_DOWN )
					{
						strPattern1 += "↓ ";
					}
					else
					{
						strPattern1 += "- ";
					}
				}
			}
		}
		
		switch ( iAxis )
		{
			case AccelValueFileData.DATA_X:
				
				m_InfectionPoint = ( TextView )findViewById( R.id.cmp_inflection_point_x1 );
				
				break;

			case AccelValueFileData.DATA_Y:
				
				m_InfectionPoint = ( TextView )findViewById( R.id.cmp_inflection_point_y );
				
				break;
			
			case AccelValueFileData.DATA_Z:
				
				m_InfectionPoint = ( TextView )findViewById( R.id.cmp_inflection_point_z );
				
				break;
		}
		
		m_InfectionPoint.setText( strPattern1 );				
	}		
	
	public void AnalyzeInflectionPoint( int iAxis , int iNumCompareFrameForPattern )
	{
		int iPattern = m_AccelValueFileData.Analyze( iAxis , iNumCompareFrameForPattern );
		
		if ( iPattern == AccelValueFileData.PATTERN_SAME )
		{
			return;
		}
		
		int iCurrentPattern = m_piCurrentPatterns[iAxis];
		int iPatternQueueIndex = m_piPatternQueueIndexs[iAxis];
		
		double fDiffThreshold = 1.0;
		
		if ( iPattern == iCurrentPattern )
		{
			double fDiff = 0.0;
			
			switch ( iAxis )
			{
				case AccelValueFileData.DATA_X:
					
					if ( iPattern == AccelValueFileData.PATTERN_UP )
					{
						double fDiffAccel = Math.abs( m_CurrAccelValue.x - m_UpPattern.x );
						
						if ( fDiffThreshold > fDiffAccel )
						{
							// 아직 업 패턴으로 선택하지 않음
						}
						else
						{
							// 패턴으로 선택됨

							int iCurrentPatternFinally = m_ppiPatterns[iAxis][iPatternQueueIndex];

							if ( iCurrentPatternFinally != iPattern )
							{
								m_ppiPatternsFinally[iAxis][iPatternQueueIndex] = iPattern;
							}
							else
							{
								// 이전 패턴과 동일하면 스킵
							}
						}
					}
					else if ( iPattern == AccelValueFileData.PATTERN_DOWN )
					{
						double fDiffAccel = Math.abs( m_CurrAccelValue.x - m_LowPattern.x );
						
						if ( fDiffThreshold > fDiffAccel )
						{
							// 아직 업 패턴으로 선택하지 않음
						}
						else
						{
							// 패턴으로 선택됨

							int iCurrentPatternFinally = m_ppiPatterns[iAxis][iPatternQueueIndex];

							if ( iCurrentPatternFinally != iPattern )
							{
								m_ppiPatternsFinally[iAxis][iPatternQueueIndex] = iPattern;
							}
							else
							{
								// 이전 패턴과 동일하면 스킵
							}
						}
					}
					
					break;

				case AccelValueFileData.DATA_Y:
					
					if ( iPattern == AccelValueFileData.PATTERN_UP )
					{
					}
					else if ( iPattern == AccelValueFileData.PATTERN_DOWN )
					{
					}
					
					break;
				
				case AccelValueFileData.DATA_Z:
					
					if ( iPattern == AccelValueFileData.PATTERN_UP )
					{
					}
					else if ( iPattern == AccelValueFileData.PATTERN_DOWN )
					{
					}
					
					break;
			}
		}
		else
		{
			// 패턴이 변경됨
			// 패턴확정에 필요한 가속도 정보 저장
			
			switch ( iAxis )
			{
				case AccelValueFileData.DATA_X:
					
					if ( iPattern == AccelValueFileData.PATTERN_UP )
					{
						m_UpPattern.x = m_CurrAccelValue.x;
					}
					else if ( iPattern == AccelValueFileData.PATTERN_DOWN )
					{
						m_LowPattern.x = m_CurrAccelValue.x;
					}
					
					break;

				case AccelValueFileData.DATA_Y:
					
					if ( iPattern == AccelValueFileData.PATTERN_UP )
					{
						m_UpPattern.y = m_CurrAccelValue.y;
					}
					else if ( iPattern == AccelValueFileData.PATTERN_DOWN )
					{
						m_LowPattern.y = m_CurrAccelValue.y;
					}
					
					break;
				
				case AccelValueFileData.DATA_Z:
					
					if ( iPattern == AccelValueFileData.PATTERN_UP )
					{
						m_UpPattern.z = m_CurrAccelValue.z;
					}
					else if ( iPattern == AccelValueFileData.PATTERN_DOWN )
					{
						m_LowPattern.z = m_CurrAccelValue.z;
					}
					
					break;
			}

			m_piCurrentPatterns[iAxis] = iPattern;
			
			m_ppiPatterns[iAxis][iPatternQueueIndex] = iPattern;
			m_piPatternQueueIndexs[iAxis] = ( ( iPatternQueueIndex + 1 ) % PATTERN_SIZE );
		}

		String strPattern = "";
		String strPattern2 = "";
		
		switch ( iAxis )
		{
			case AccelValueFileData.DATA_X:
				
				strPattern += "X(R) : ";
				
				break;

			case AccelValueFileData.DATA_Y:
				
				strPattern += "Y(G) : ";
				
				break;
			
			case AccelValueFileData.DATA_Z:
				
				strPattern += "Z(B) : ";
				
				break;
		}

		for ( int i = m_piPatternQueueIndexs[iAxis] ; i < PATTERN_SIZE ; i++ )
		{
			if ( m_ppiPatterns[iAxis][i] != 0 )
			{
				if ( m_ppiPatterns[iAxis][i] > 0 )
				{
					strPattern += "↑ "; 
				}
				else
				{
					strPattern += "↓ ";
				}

				if ( m_ppiPatternsFinally[iAxis][i] > 0 )
				{
					strPattern2 += "↑ "; 
				}
				else if ( m_ppiPatternsFinally[iAxis][i] < 0 )
				{
					strPattern2 += "↓ ";
				}
				else
				{
					strPattern2 += " ";
				}
			}
		}
		
		for ( int i = 0 ; i < m_piPatternQueueIndexs[iAxis] - 1 ; i++ )
		{
			if ( m_ppiPatterns[iAxis][i] != 0 )
			{
				if ( m_ppiPatterns[iAxis][i] > 0 )
				{
					strPattern += "↑ "; 
				}
				else
				{
					strPattern += "↓ ";
				}

				if ( m_ppiPatternsFinally[iAxis][i] > 0 )
				{
					strPattern2 += "↑ "; 
				}
				else if ( m_ppiPatternsFinally[iAxis][i] < 0 )
				{
					strPattern2 += "↓ ";
				}
				else
				{
					strPattern2 += " ";
				}
			}
		}
		
		switch ( iAxis )
		{
			case AccelValueFileData.DATA_X:
				
				m_InfectionPoint = ( TextView )findViewById( R.id.cmp_inflection_point_x1 );
				m_InfectionPoint2 = ( TextView )findViewById( R.id.cmp_inflection_point_x2 );
				
				break;

			case AccelValueFileData.DATA_Y:
				
				m_InfectionPoint = ( TextView )findViewById( R.id.cmp_inflection_point_y );
				
				break;
			
			case AccelValueFileData.DATA_Z:
				
				m_InfectionPoint = ( TextView )findViewById( R.id.cmp_inflection_point_z );
				
				break;
		}
		
		m_InfectionPoint.setText( strPattern );				
		m_InfectionPoint2.setText( strPattern2 );
	}
	
	/*
	public void AnalyzeInflectionPoint( int iAxis , int iNumCompareFrameForPattern )
	{
		int iPattern = m_AccelValueFileData.Analyze( iAxis , iNumCompareFrameForPattern );
		
		if ( iPattern == AccelValueFileData.PATTERN_SAME )
		{
			return;
		}
		
		int iCurrentPattern = m_piCurrentPatterns[iAxis];
		int iPatternQueueIndex = m_piPatternQueueIndexs[iAxis];
		
		if ( iPattern != iCurrentPattern )
		{
			switch ( iAxis )
			{
				case AccelValueFileData.DATA_X:
					
					if ( iPattern == AccelValueFileData.PATTERN_UP )
					{
						m_UpPattern.x = m_CurrAccelValue.x;
					}
					else if ( iPattern == AccelValueFileData.PATTERN_DOWN )
					{
					}
					
					break;

				case AccelValueFileData.DATA_Y:
					
					if ( iPattern == AccelValueFileData.PATTERN_UP )
					{
					}
					else if ( iPattern == AccelValueFileData.PATTERN_DOWN )
					{
					}
					
					break;
				
				case AccelValueFileData.DATA_Z:
					
					if ( iPattern == AccelValueFileData.PATTERN_UP )
					{
					}
					else if ( iPattern == AccelValueFileData.PATTERN_DOWN )
					{
					}
					
					break;
			}

			
			m_piCurrentPatterns[iAxis] = iPattern;
			
			m_ppiPatterns[iAxis][iPatternQueueIndex] = iPattern;
			m_piPatternQueueIndexs[iAxis] = ( ( iPatternQueueIndex + 1 ) % PATTERN_SIZE );
			
			String strPattern = "";
			
			switch ( iAxis )
			{
				case AccelValueFileData.DATA_X:
					
					strPattern += "X(R) : ";
					
					break;

				case AccelValueFileData.DATA_Y:
					
					strPattern += "Y(G) : ";
					
					break;
				
				case AccelValueFileData.DATA_Z:
					
					strPattern += "Z(B) : ";
					
					break;
			}

			for ( int i = m_piPatternQueueIndexs[iAxis] ; i < PATTERN_SIZE ; i++ )
			{
				if ( m_ppiPatterns[iAxis][i] != 0 )
				{
					if ( m_ppiPatterns[iAxis][i] > 0 )
					{
						strPattern += "↑ "; 
					}
					else
					{
						strPattern += "↓ ";
					}
				}
			}
			
			for ( int i = 0 ; i < m_piPatternQueueIndexs[iAxis] - 1 ; i++ )
			{
				if ( m_ppiPatterns[iAxis][i] != 0 )
				{
					if ( m_ppiPatterns[iAxis][i] > 0 )
					{
						strPattern += "↑ "; 
					}
					else
					{
						strPattern += "↓ ";
					}
				}
			}
			
			switch ( iAxis )
			{
				case AccelValueFileData.DATA_X:
					
					m_InfectionPoint = ( TextView )findViewById( R.id.cmp_inflection_point_x );
					
					break;

				case AccelValueFileData.DATA_Y:
					
					m_InfectionPoint = ( TextView )findViewById( R.id.cmp_inflection_point_y );
					
					break;
				
				case AccelValueFileData.DATA_Z:
					
					m_InfectionPoint = ( TextView )findViewById( R.id.cmp_inflection_point_z );
					
					break;
			}
			
			m_InfectionPoint.setText( strPattern );				
		}
		else
		{
		}
	}
	*/
	
	public boolean VerifyStartedActivity( Axis3f prev , Axis3f curr )
	{
		SmartFitApp app = ( ( SmartFitApp )getApplicationContext() );
		
		Axis3f diff = new Axis3f();
		
		diff.x = curr.x - prev.x;
		diff.y = curr.y - prev.y;
		diff.z = curr.z - prev.z;
		
		Axis3f reviced = new Axis3f();
		
		double fConstant1 = app.m_ExamplarDB.GetCheckStartConstant1();
		double fConstant2 = app.m_ExamplarDB.GetCheckStartConstant2();
		
		reviced.x = ( fConstant1 * ( curr.x * curr.x ) ) + ( fConstant2 * ( diff.x * diff.x ) );
		reviced.y = ( fConstant1 * ( curr.y * curr.y ) ) + ( fConstant2 * ( diff.y * diff.y ) );
		reviced.z = ( fConstant1 * ( curr.z * curr.z ) ) + ( fConstant2 * ( diff.z * diff.z ) );
		
		double fThreshold = app.m_ExamplarDB.GetCheckStartThreshold();
		
		if ( ( reviced.x < fThreshold ) && ( reviced.y < fThreshold ) && ( reviced.z < fThreshold ) ) 
		{
			return false;
		}
		else
		{
			return true;
		}
	}

	@Override
	public void NotifySensorDistanceEvent( double x , double y , double z )
	{
		// TODO Auto-generated method stub
		
		if ( m_bIsStarted )
		{
			m_AccelValueFileData.Set( AccelValueFileData.DATA_TYPE_DISTANCE , x , y , z );
		}
	}
	
	protected void Compare()
	{
		SmartFitApp app = ( ( SmartFitApp )getApplicationContext() );
		
		CompareResult r = new CompareResult();
		

		String strResult = null;
		
		if ( app.m_ExamplarDB.Compare( m_AccelValueFileData , r ) )
		{
			strResult = "FOUND" +
					" , ID : " + String.valueOf( r.iID ) +
					" , Angle : " + m_DecimalFormat.format( r.fAccelerate ) +
					" , Distance : " + m_DecimalFormat.format( r.fDistance );
		}
		else
		{
			strResult = "NOT FOUND";
		}
		
		m_Result.setText( strResult );
		

		
		ArrayList<String> arrHistory = new ArrayList<String>();
		
		Axis3f currDataDistance = m_AccelValueFileData.GetDistance();
		String strDistance = 
				" : x = " + m_DecimalFormat.format( currDataDistance.x ) + 
				" , y = " + m_DecimalFormat.format( currDataDistance.y ) + 
				" , z = " + m_DecimalFormat.format( currDataDistance.z );

		arrHistory.add( "Current Distance Data" + strDistance );
		arrHistory.add( "Current Angle Data" );
		
		int iNumCurrentData = m_AccelValueFileData.m_Angle.accelValueXs.size();
		
		for ( int i = 0 ; i < iNumCurrentData ; i++ )
		{
			String s = 
					Integer.toString( i ) + 
					" : a.x = " + m_DecimalFormat.format( m_AccelValueFileData.m_Angle.accelValueXs.get( i ) ) + 
					" , a.y = " + m_DecimalFormat.format( m_AccelValueFileData.m_Angle.accelValueYs.get( i ) ) +
					" , a.z = " + m_DecimalFormat.format( m_AccelValueFileData.m_Angle.accelValueZs.get( i ) ) +
					" , d.x = " + m_DecimalFormat.format( m_AccelValueFileData.m_Distance.accelValueXs.get( i ) ) +
					" , d.y = " + m_DecimalFormat.format( m_AccelValueFileData.m_Distance.accelValueYs.get( i ) ) +
					" , d.z = " + m_DecimalFormat.format( m_AccelValueFileData.m_Distance.accelValueZs.get( i ) );
			
			arrHistory.add( s );

			// 라인 차트
			//m_ChartLine.Add( m_AccelValueFileData.m_Angle.accelValueXs.get( i ) , m_AccelValueFileData.m_Angle.accelValueYs.get( i ) , m_AccelValueFileData.m_Angle.accelValueZs.get( i ) );
		}
		
		// 라인차트
		//m_ChartLine.ReDrawChart();
		
		arrHistory.add( "----------------------------------------------" );
		arrHistory.add( "Examplar Data" );

		int iNumExamplar = r.m_CompareHistories.size();
		for ( int i = 0 ; i < iNumExamplar ; i++ )
		{
			CompareHistory h = r.m_CompareHistories.get( i );
			
			int iNumHistory = h.m_Histories.size();
			
			for ( int j = 0 ; j < iNumHistory ; j++ )
			{
				CompareHistory.History item = h.m_Histories.get( j );
				
				String s = "ID : " + Integer.toString( i ) +
						" , a = " + m_DecimalFormat.format( item.fAngle ) + 
						" , d = " + m_DecimalFormat.format( item.fDistance );
				
				arrHistory.add( s );
			}
		}
		
		CompareHistoryAdapter historyAdapter = new CompareHistoryAdapter( this , R.id.compare_history_list , arrHistory );
		m_ListView.setAdapter( historyAdapter );
		
		SetListViewHeightBasedOnChildren( m_ListView );
	}
	
	private void ShowNotFoundExamplar()
	{
		AlertDialog.Builder alertDlg = new AlertDialog.Builder( this );
		
		alertDlg.setTitle( "Notice" );
		alertDlg.setPositiveButton( "OK" ,
				new DialogInterface.OnClickListener()
				{
				    @Override
				    public void onClick( DialogInterface dialog , int which )
				    {
				    	dialog.dismiss();
				    }
			    }
		);
		alertDlg.setMessage( "Not found id" );
		alertDlg.show();
	}

	public static void SetListViewHeightBasedOnChildren( ListView listView )
	{
        ListAdapter listAdapter = listView.getAdapter(); 
        
        if ( listAdapter == null )
        {
            // pre-condition
            return;
        }
 
        int totalHeight = 0;
        
        for ( int i = 0 ; i < listAdapter.getCount() ; i++ )
        {
            View listItem = listAdapter.getView( i , null , listView );
            listItem.measure( 0 , 0 );
            
            totalHeight += listItem.getMeasuredHeight();
        }
 
        ViewGroup.LayoutParams params = listView.getLayoutParams();
        params.height = totalHeight + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
        listView.setLayoutParams(params);
        listView.requestLayout();

	}
}